namespace PugLib.Benchmarks
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using Extensions.Collections;

    public static class Loops
    {
        public static TestResult ListIntGenericsForEachCountOuter()
        {
            Console.WriteLine("ListIntGenericsForEachCountOuter");
            TestResult trd = new TestResult("ListIntGenericsForEachCountOuter");
            Int64 total = 0;
            List<int> li = Factory.GenerateRepeatedList(1, Statics.ItemCount);

            trd.Start();
            for (int i = 0; i < (int)Statics.Max; i++)
            {
                li.ForEach(foo => total += foo);
            }
            trd.Stop();

            Debug.Assert(total == Statics.AssertValue);
            return trd;
        }

        public static TestResult ListIntGenericsForEachLambda()
        {
            Console.WriteLine("ListIntGenericsForEachLambda");
            TestResult trd = new TestResult("ListIntGenericsForEachLambda");
            Int64 total = 0;
            List<int> li = Factory.GenerateRepeatedList(1, Statics.ItemCount);

            trd.Start();
            for (int i = 0; i < Statics.Max; i++)
            {
                li.ForEach(foo => total += foo);
            }
            trd.Stop();

            Debug.Assert(total == Statics.AssertValue);
            return trd;
        }

        public static TestResult ListIntGenericsForEachDelegate()
        {
            Console.WriteLine("ListIntGenericsForEachDelegate");
            TestResult trd = new TestResult("ListIntGenericsForEachDelegate");
            Int64 total = 0;
            List<int> li = Factory.GenerateRepeatedList(1, Statics.ItemCount);

            trd.Start();
            for (int i = 0; i < Statics.Max; i++)
            {
                li.ForEach(delegate(int foo) { total += foo; });
            }
            trd.Stop();


            Debug.Assert(total == Statics.AssertValue);
            return trd;
        }


        public static TestResult ListIntForEach()
        {
            Console.WriteLine("ListIntForeach");
            TestResult trd = new TestResult("ListIntForeach");
            Int64 total = 0;
            List<int> li = Factory.GenerateRepeatedList(1, Statics.ItemCount);

            trd.Start();
            for (int i = 0; i < Statics.Max; i++)
            {
                foreach (int foo in li)
                {
                    total += foo;
                }
            }
            trd.Stop();

            Debug.Assert(total == Statics.AssertValue);
            return trd;
        }

        public static TestResult ListIntForUsingCount()
        {
            Console.WriteLine("ListIntForUsingCount");
            TestResult trd = new TestResult("ListIntForUsingCount");
            Int64 total = 0;
            List<int> li = Factory.GenerateRepeatedList(1, Statics.ItemCount);

            trd.Start();
            for (int i = 0; i < Statics.Max; i++)
            {
                for (int iter = 0; iter < li.Count; iter++)
                {
                    total += li[iter];
                }
            }
            trd.Stop();


            Debug.Assert(total == Statics.AssertValue);
            return trd;
        }

        public static TestResult ListIntForCachingCount()
        {
            Console.WriteLine("ListIntForCachingCount");
            TestResult trd = new TestResult("ListIntForCachingCount");
            Int64 total = 0;
            List<int> li = Factory.GenerateRepeatedList(1, Statics.ItemCount);


            trd.Start();
            for (int i = 0; i < Statics.Max; i++)
            {
                for (int iter = 0; iter < Statics.ItemCount; iter++)
                {
                    total += li[iter];
                }
            }
            trd.Stop();


            Debug.Assert(total == Statics.AssertValue);
            return trd;
        }

        public static TestResult ListToArray()
        {
            Console.WriteLine("ListToArray");
            TestResult trd = new TestResult("ListToArray");
            Int64 total = 0;
            List<int> li = Factory.GenerateRepeatedList(1, Statics.ItemCount);


            trd.Start();

            // convert to an array
            int[] arr = li.ToArray();

            for (int i = 0; i < Statics.Max; i++)
            {
                for (int iter = 0; iter < arr.Length; iter++)
                {
                    total += arr[iter];
                }
            }
            trd.Stop();

            Debug.Assert(total == Statics.AssertValue);
            return trd;
        }

        public static TestResult ArrayFor()
        {
            Console.WriteLine("ArrayFor");
            TestResult trd = new TestResult("ArrayFor");
            Int64 total = 0;
            int[] li = new int[Statics.ItemCount];

            for (int i = 0; i < Statics.ItemCount; i++)
            {
                li[i] = 1;
            }


            trd.Start();
            for (int i = 0; i < Statics.Max; i++)
            {
                for (int iter = 0; iter < li.Length; iter++)
                {
                    total += li[iter];
                }
            }
            trd.Stop();

            Debug.Assert(total == Statics.AssertValue);
            return trd;
        }

        public static TestResult ArrayForEach()
        {
            Console.WriteLine("ArrayForEach");
            TestResult trd = new TestResult("ArrayForEach");
            Int64 total = 0;
            int[] li = new int[Statics.ItemCount];

            for (int i = 0; i < Statics.ItemCount; i++)
            {
                li[i] = 1;
            }

            trd.Start();
            for (int i = 0; i < Statics.Max; i++)
            {
                foreach (int iter in li)
                {
                    total += iter;
                }
            }
            trd.Stop();

            Debug.Assert(total == Statics.AssertValue);
            return trd;
        }

        public static TestResult ArrayForEachExtension()
        {
            Console.WriteLine("ArrayForEachExtension");
            TestResult trd = new TestResult("ArrayForEachExtension");
            Int64 total = 0;
            int[] li = new int[Statics.ItemCount];

            for (int i = 0; i < Statics.ItemCount; i++)
            {
                li[i] = 1;
            }

            trd.Start();
            for (int i = 0; i < Statics.Max; i++)
            {
                li.ForEach(iter => total += iter);
            }
            trd.Stop();

            Debug.Assert(total == Statics.AssertValue);
            return trd;
        }
    }
}